<template>
<div>
<!--  面包屑区域-->
  <el-breadcrumb separator="/">
    <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
    <el-breadcrumb-item>权限管理</el-breadcrumb-item>
    <el-breadcrumb-item>角色列表</el-breadcrumb-item>
  </el-breadcrumb>
<!--  卡片视图-->
  <el-card>
    <el-row>
      <el-col>
        <el-button type="primary" @click="showAddDialog">
          添加角色
        </el-button>
      </el-col>
    </el-row>
<!--    角色列表区域-->
    <el-table
        :data="rolesList"
        stripe
        border
        style="width: 100%">
      <el-table-column type="expand" align="center">
        <template slot-scope="scope">
          <el-row v-for="(item1,i1) in scope.row.children" :key="item1.id" :class="['tagBotm',i1===0?'tagTop':'','vcenter']">
<!--            一级权限-->
            <el-col :span="5">
              <el-tag closable @close="removeTagByID(scope.row,item1.id)">{{item1.authName}}</el-tag>
              <i class="el-icon-caret-right"></i>
            </el-col>
<!--            二三级权限-->
            <el-col :span="19">
              <el-row v-for="(item2,i2) in item1.children" :key="item2.id" :class="[i2===0 ?'':'tagTop','vcenter']">
                <el-col :span="6">
                  <el-tag type="success" closable @close="removeTagByID(scope.row,item2.id)">{{item2.authName}}</el-tag>
                  <i class="el-icon-caret-right"></i>
                </el-col>
                <el-col :span="13">
                  <el-tag v-for="(item3,i3) in item2.children" :key="item3.id" type="warning" closable @close="removeTagByID(scope.row,item3.id)">
                    {{item3.authName}}
                  </el-tag>
                </el-col>
              </el-row>
            </el-col>
          </el-row>
        </template>
      </el-table-column>
      <el-table-column type="index" align="center"></el-table-column>
      <el-table-column
          prop="roleName"
          label="角色名称"
          align="center">
      </el-table-column>
      <el-table-column
          prop="roleDesc"
          label="角色描述"
          align="center">
      </el-table-column>
      <el-table-column
          prop="roleDesc"
          label="操作"
          align="center">
        <template slot-scope="scope">
          <!--            修改-->
          <el-button type="primary" icon="el-icon-edit" size="mini" @click="editRole(scope.row.id)">编辑</el-button>
          <!--            删除-->
          <el-button type="danger" icon="el-icon-delete"  size="mini" @click="deleteRole(scope.row.id)">删除</el-button>
          <!--            分配角色-->
            <el-button type="warning" icon="el-icon-setting"  size="mini" @click="showSetRightsDialog(scope.row)">分配权限</el-button>
        </template>
      </el-table-column>
    </el-table>
  </el-card>
<!--  添加角色的对话框-->
  <el-dialog
      title="添加角色"
      :visible.sync="addDialogVisible"
      width="50%"
      @close="restForm"
      >
<!--   添加角色表单区域-->
    <el-form :model="roleForm" status-icon :rules="roleRules" ref="roleRef" label-width="100px" class="demo-ruleForm">
      <el-form-item label="角色名称" prop="roleName">
        <el-input  v-model="roleForm.roleName" ></el-input>
      </el-form-item>
      <el-form-item label="角色描述" prop="roleDesc">
        <el-input  v-model="roleForm.roleDesc" ></el-input>
      </el-form-item>
    </el-form>
    <span slot="footer" class="dialog-footer">
    <el-button @click="addDialogVisible = false">取 消</el-button>
    <el-button type="primary" @click="addRole">确 定</el-button>
  </span>
  </el-dialog>
<!--  编辑角色的对话框-->
  <el-dialog
      title="修改角色"
      :visible.sync="editDialogVisible"
      width="50%"
      @close="editDialogClosed"
      >
<!--    修改角色的表单区域-->
    <el-form ref="editRef" :model="editForm" label-width="80px" :rules="editRules">
      <el-form-item label="角色名称" prop="roleName">
        <el-input v-model="editForm.roleName"></el-input>
      </el-form-item>
      <el-form-item label="角色描述" prop="roleDesc">
        <el-input v-model="editForm.roleDesc"></el-input>
      </el-form-item>
    </el-form>
    <span slot="footer" class="dialog-footer">
    <el-button @click="editDialogVisible = false">取 消</el-button>
    <el-button type="primary" @click="submitEdit()">确 定</el-button>
  </span>
  </el-dialog>
<!--  分配角色对话框-->
  <el-dialog
      title="分配权限"
      :visible.sync="setRightDialogVisible"
      width="50%"
      @close="setRightDialogClosed"
    >
<!--    树形结构-->
    <el-tree :data="rightsList" :props="treeProps" show-checkbox node-key="id" :default-expand-all="true" :default-checked-keys="defKeys" ref="treeRef"></el-tree>
    <span slot="footer" class="dialog-footer">
    <el-button @click="setRightDialogVisible = false">取 消</el-button>
    <el-button type="primary" @click="allotRights">确 定</el-button>
  </span>
  </el-dialog>

</div>
</template>

<script>
export default {
  name: "roles",
  data(){
    return{
      // 添加角色对话框
      addDialogVisible:false,
      // 修改角色的对话框显示或隐藏
      editDialogVisible:false,
      // 分配权限对话框
      setRightDialogVisible:false,

      // 角色列表对象
      rolesList:[],
      // 添加角色表单数据对象
      roleForm:{
        roleName:'',
        roleDesc:''
      },
      // 修改角色数据对象
      editForm:{

      },
      treeProps:{
        children: 'children',
        label: 'authName'
      },
        // 添加角色表单数据验证对象
      roleRules:{
        roleName:[
          {required:true,message:'角色名称不能为空',trigger:'blur'}
    ],
        roleDesc:[
          {required:true,message:'角色描述不能为空',trigger:'blur'}
        ]
  },
      // 权限列表
      rightsList:[],
      // 默认选中的节点的id值列表
      defKeys:[],
      // 当前即将分配权限的id
      roleId:'',
  // 修改角色的表单验证
      editRules:{
        roleName:[
          {required:true,message:'角色名称不能为空',trigger:'blur'}
        ],
        roleDesc:[
          {required:true,message:'角色描述不能为空',trigger:'blur'}
        ]
      },
    }
  },
  // 当组件被渲染时就发起角色的请求
  created() {
    this.getRolesList();
  },
  methods:{
   async getRolesList(){
      const {data:res}=await this.$http.get('roles');
      if(res.meta.status !==200){
        return this.$message.error("获取角色列表失败")
      }
      // 获取角色列表成功
     this.rolesList=res.data;
   },
    // 添加角色按钮
   async addRole(){
    this.$refs.roleRef.validate(async valid =>{
      if(!valid) return;
      // 发起添加角色的请求
      const {data:res}=await this.$http.post('roles',this.roleForm);
      if(res.meta.status !==201){
        return this.$message.error("提交角色失败");
      }
      // 提交角色成功
      this.$message.success("添加角色成功");
      this.getRolesList();
      this.addDialogVisible=false;
    })

    },
    // 提交角色对话框显示
    showAddDialog(){
      this.addDialogVisible=true;
    },
    // 修改角色对话框关闭重置表单
    editDialogClosed(){
     this.$refs.editRef.resetFields();
    },
    // 点击编辑按钮，首先根据id获取相应角色信息，再显示对话框
   async editRole(id){
     const {data:res}=await this.$http.get('roles/'+id);
     if(res.meta.status !==200){
       return;
     }
     // 请求成功
     this.editForm=res.data;
     this.editDialogVisible=true;
    },
    // 点击确定修改，想服务器提交修改的数据
    submitEdit(){
     this.$refs.editRef.validate(async valid=>{
       if(!valid){
         return;
       }
       // 通过验证，发送数据 请求参数名一定要正确
       const {data:res}=await this.$http.put('roles/'+this.editForm.roleId,{
         roleName:this.editForm.roleName,
         roleDesc:this.editForm.roleDesc
       });
       if(res.meta.status !==200){
         return this.$message.error("修改角色信息失败")
       }
       // 修改成功
       this.$message.success("修改角色成功");
       this.getRolesList();
       this.editDialogVisible=false;
     })
    },
    // 删除角色
  async deleteRole(id){
        // 用户点击删除按钮，弹出一个确认框
      const confirmResult= await  this.$confirm('此操作将删除该角色, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }).catch(err=>err)
    // 判断用户点的什么
    if(confirmResult ==='cancel'){
      return this.$message.info("已经取消删除");
    }
    // 用户确定删除该角色
    const {data:res}=await this.$http.delete('roles/'+id);
    if(res.meta.status!==200){
      return this.$message.error('删除该角色失败')
    }
    this.$message.success("成功删除该角色");
    this.getRolesList();
    },
    // 重置添加角色表单数据
    restForm(){
     this.$refs.roleRef.resetFields();
    },
    // 根据id删除对应权限
   async removeTagByID(role,rightsID){
   //    弹框提示用户是否删除权限
      const confirmResult= await  this.$confirm('此操作将永久删除该权限, 是否继续?', '提示', {
       confirmButtonText: '确定',
      cancelButtonText: '取消',
     type: 'warning',
    }).catch(err=>err);
      if(confirmResult=='cancel'){
        return this.$message.info("已经取消删除")
      }
      const {data:res}=await this.$http.delete(`roles/${role.id}/rights/${rightsID}`);
      if(res.meta.status !==200){
        return this.$message.error("删除权限失败")
      }
      // 删除权限成功，重新获取权限
     this.$message.success("删除权限成功");
      // this.getRolesList();
     // 放在页面再次刷新
     role.children=res.data;
    },
    // 展示分配权限的对话框
   async showSetRightsDialog(role){
     this.roleId=role.id;
     // console.log(this.roleId);
     // 获取所有权限列表
      const {data:res}=await this.$http.get('rights/tree');
      if(res.meta.status !==200){
        return this.$message.error('获取权限列表失败');
      }
      //获取成功
      //   this.$message.success("获取权限列表成功");
      this.rightsList=res.data;
      // 当分配权限对话框打开时，先获取所有角色已经有的三级权限
        this.getLeafKeys(role,this.defKeys);
        this.setRightDialogVisible=true;
    },
    // 通过递归的方法去获取所有三级权限的id
    getLeafKeys(node,arr){
     // 如果当前节点没有children ，则该节点是三级权限节点
     if(!node.children){
       return arr.push(node.id);
     }
     // 不是三级权限节点
      node.children.forEach(item=>
      this.getLeafKeys(item,arr))
    },
    // 监听分配权限对话框的关闭事件
    setRightDialogClosed() {
      this.defKeys = []
    },
    // 点击确定为角色分配权限
   async allotRights(){
     // 展开运算符
      const keys=[
          ...this.$refs.treeRef.getCheckedKeys(),
          ...this.$refs.treeRef.getHalfCheckedKeys()
      ];
      const idStr=keys.join(',');
   const {data:res}=await this.$http.post(`roles/${this.roleId}/rights`,{rids:idStr});
   if(res.meta.status !==200){
     return this.$message.error("分配权限失败")
   }
   // 分配权限成功
     this.$message.success("分配权限成功");
   this.getRolesList();
   this.setRightDialogVisible=false;
    },

  }
}
</script>

<style scoped>
.el-tag{
  margin: 15px;
}
.tagTop{
  border-top: 1px solid #eee;
}
.tagBotm{
  border-bottom: 1px solid #eee;
}
.vcenter{
  display: flex;
  align-items: center;
}
</style>